﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Xml;
using System.Xml.Linq;

namespace EDMXFix
{
    /// <summary>
    /// Logique d'interaction pour MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Visibility = System.Windows.Visibility.Hidden;
            bool showWindow = false;

            string[] args = Environment.GetCommandLineArgs();
            if (args.Length > 0)
            {
                var dictionary = new Dictionary<string, string>();
                for (int index = 1; index < args.Length; index += 2)
                {
                    dictionary.Add(args[index], args[index + 1]);
                }

                if (dictionary.ContainsKey("Source"))
                {
                    var src = dictionary["Source"];

                    var dest = src;
                    if (dictionary.ContainsKey("Output"))
                    {
                        dest = dictionary["Output"];
                    }

                    if (IsInputValid(src, dest))
                    {
                        Fix(src, dest);
                        Console.WriteLine("It's fixed !");
                        Close();
                    }
                }
                else
                {
                    showWindow = true;
                }
            }
            else
            {
                showWindow = true;
            }


            if (showWindow)
            {
                Visibility = System.Windows.Visibility.Visible;
            }
        }

        private bool IsInputValid(string src, string dest)
        {
            if (!File.Exists(src))
            {
                MessageBox.Show("File not found");
                return false;
            }

            return true;
        }

        private void Process_Click(object sender, RoutedEventArgs e)
        {
            if (IsInputValid(InputFilePath.Text, InputFilePath.Text))
            {
                try
                {
                    Fix(InputFilePath.Text, InputFilePath.Text);
                }
                catch (Exception)
                {
                    MessageBox.Show("Error");
                    return;
                }

                MessageBox.Show("It's fixed !");
            }
        }

        private void Fix(string src, string dest)
        {
            XDocument doc = XDocument.Load(src);

            var functionElements = doc.Root.DescendantNodes()
                                           .OfType<XElement>()
                                           .Where(x => x.Name.LocalName == "Function")
                                           ;

            foreach (var function in functionElements)
            {
                // for each parameters
                var parametersElements = function.DescendantNodes()
                                                 .OfType<XElement>()
                                                 .Where(x => x.Name.LocalName == "Parameter")
                                                 ;
                var dirtyParameters = from x in parametersElements
                                      where String.Equals(x.Attribute("Type").Value, "numeric")
                                      || String.Equals(x.Attribute("Type").Value, "decimal")
                                      select x;

                foreach (var parameter in dirtyParameters)
                {
                    // if it doesn't have the attribute Precision="20" add it
                    if (parameter.Attribute("Precision") == null)
                    {
                        var xName = XName.Get("Precision");
                        var value = 20;
                        parameter.SetAttributeValue(xName, value);
                    }

                    // if it doesn't have the attribute Scale="5" add it
                    if (parameter.Attribute("Scale") == null)
                    {
                        var xName = XName.Get("Scale");
                        var value = 5;
                        parameter.SetAttributeValue(xName, value);
                    }
                }

                doc.Save(dest);
            }
        }
    }
}
